从一个 结构体 到一个 抽象数据类型(ADT) 标志着设计哲学的根本转变。虽然一个 结构体 通常只是变量的被动集合,而抽象数据类型则是一个主动实体,通过 封装来管理自身的状态。
1. 设计意图
在C++中, class 关键字表明了对 数据抽象的承诺。该策略将 接口 (用户可以执行的操作)与 实现 (数据如何存储)分离开来。通过屏蔽内部变量,程序员确保对象能够保持其自身的内部一致性。
2. 技术细节
从技术上讲,一个 结构体 和一个 class 在C++中的唯一区别是 默认访问级别。一个 结构体 的成员默认是 公共的 ,反映了它们作为开放数据持有者的角色。一个 class 的成员默认是 的成员默认是 ,反映了它们作为受控实体的角色。
$$\text{ADT} = \text{数据} + \text{操作}$$
main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>
QUESTION 1
What is the primary technical difference between a 'struct' and a 'class' in C++?
Structs cannot have member functions.
Classes are stored on the heap while structs are on the stack.
The default access level (public for struct, private for class).
Only classes support inheritance.
✅ Correct!
Correct! It is purely a matter of default access levels to facilitate different design intents.❌ Incorrect
Both can have functions and inheritance; the difference lies in default access permissions.QUESTION 2
What is the goal of 'Data Abstraction'?
To make the code run faster by removing data types.
To separate a type's interface from its implementation.
To allow variables to hold multiple types at once.
To prevent the use of pointers in a class.
✅ Correct!
Yes! Abstraction lets users interact with 'what it does' without worrying about 'how it works'.❌ Incorrect
Abstraction is about the logical separation of interface and implementation detail.QUESTION 3
If a class defines an operation 'combine()', who is responsible for maintaining internal consistency?
The user calling the function.
The operating system.
The class itself via its member functions.
The C++ compiler's garbage collector.
✅ Correct!
Exactly. An ADT manages its own state to ensure internal data remains logical.❌ Incorrect
In an ADT, the class encapsulates the logic to ensure data integrity.QUESTION 4
Why would the initialization 'Sales_data item = "9-999";' fail if it requires two conversions?
C++ allows zero implicit conversions.
C++ allows only one implicit user-defined conversion at a time.
Strings cannot be converted to objects.
Implicit conversions are only allowed for numeric types.
✅ Correct!
Correct. Converting char* to string and then string to Sales_data is one step too many for the compiler.❌ Incorrect
The compiler limits implicit user-defined chains to a single step to prevent ambiguity.QUESTION 5
In the provided code snippet, why is 'my_mem' accessible in main()?
Because it was declared in a struct and is public by default.
Because main() is a friend of struct A.
Because it is a static member.
Because all strings are globally accessible.
✅ Correct!
Indeed. Struct members default to public, allowing external access.❌ Incorrect
Check the default access level of a struct—it's public!Module Implementation Task: The Employee ADT
Applying Encapsulation and Static Members
You are tasked with creating a robust Employee management class. To ensure every employee has a unique identifier, you must use a shared counter that increments with every new instance. This demonstrates encapsulation and class-wide state management.
Q
[Writing Task] Exercise 13.18: Define an Employee class that contains an employee name and a unique employee identifier. Give the class a default constructor and a constructor that takes a string. Each should generate a unique ID. (Min 50 words code/explanation)
Solution:
To implement this, we define a static member `sn` to keep track of the next available ID. cpp class Employee { public: Employee() : id(sn++) { } Employee(const std::string& s) : name(s), id(sn++) { } private: std::string name; int id; static int sn; }; int Employee::sn = 0; // Initialize outside class This design ensures that the unique ID generation is handled internally by the class (encapsulation), and the shared state is maintained across all instances via the static member.
To implement this, we define a static member `sn` to keep track of the next available ID. cpp class Employee { public: Employee() : id(sn++) { } Employee(const std::string& s) : name(s), id(sn++) { } private: std::string name; int id; static int sn; }; int Employee::sn = 0; // Initialize outside class This design ensures that the unique ID generation is handled internally by the class (encapsulation), and the shared state is maintained across all instances via the static member.
Q
Explain why the initialization 'Sales_data item = {"978-0590353403", 25, 15.99};' would fail if any member of Sales_data were made private.
Solution:
This is aggregate initialization. It relies on the class being an aggregate, which requires all data members to be public and for there to be no user-defined constructors. Once you introduce the 'private' keyword for encapsulation, the class is no longer an aggregate, and you must instead provide a constructor that matches the provided argument list to initialize the object.
This is aggregate initialization. It relies on the class being an aggregate, which requires all data members to be public and for there to be no user-defined constructors. Once you introduce the 'private' keyword for encapsulation, the class is no longer an aggregate, and you must instead provide a constructor that matches the provided argument list to initialize the object.